const dayjs = require('dayjs');
/**
 * Notes: 微信缓存二次封装，有设置时效性的封装
 * Ver : CCMiniCloud Framework 3.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2020-11-14 07:48:00 
 */
const helper = require('./helper.js');

const TIME_SUFFIX = "_deadtime"

// 缓存分组
const CACHE_GROUP = {
    SYSTEM: 'system',    // 系统缓存
    USER: 'user',        // 用户相关缓存
    LIST: 'list',        // 列表数据缓存
    DETAIL: 'detail',    // 详情数据缓存
    CONFIG: 'config',    // 配置缓存
    TEMP: 'temp'         // 临时缓存
};

// 缓存优先级
const CACHE_PRIORITY = {
    HIGH: 3,    // 高优先级，最后清理
    NORMAL: 2,  // 普通优先级
    LOW: 1      // 低优先级，最先清理
};

/**
 * 设置
 * k 键key
 * v 值value
 * t 秒
 */
function set(k, v, t = 86400 * 30) {
	if (!k) return null;

	wx.setStorageSync(k, v);
	let seconds = parseInt(t);
	if (seconds > 0) {
		let newtime = Date.parse(dayjs());
		newtime = newtime / 1000 + seconds;
		wx.setStorageSync(k + TIME_SUFFIX, newtime + "");
	} else {
		wx.removeStorageSync(k + TIME_SUFFIX);
	}
}
 

/**
 * 获取
 * k 键key
 * def 默认值
 */
function get(k, def = null) {
	if (!k) return null;

	let deadtime = wx.getStorageSync(k + TIME_SUFFIX); 
	if (!deadtime) return def;
 
	deadtime = parseInt(deadtime); 
	if (!deadtime) return def;
	
	if (deadtime) {
		if (parseInt(deadtime) < Date.parse(dayjs()) / 1000) {
			wx.removeStorageSync(k); 
			wx.removeStorageSync(k + TIME_SUFFIX); 
			return def;
		}
	} 

	let res = wx.getStorageSync(k);
 
	if (helper.isDefined(res)) {
		return res;
	} else {
		return def;
	}
}

/**
 * 检查缓存是否存在且未过期
 * @param {String} k 键名
 * @returns {Boolean} 是否存在且未过期
 */
function has(k) {
	if (!k) return false;

	let deadtime = wx.getStorageSync(k + TIME_SUFFIX); 
	if (!deadtime) return false;
 
	deadtime = parseInt(deadtime); 
	if (!deadtime) return false;
	
	// 判断是否过期
	if (parseInt(deadtime) < Date.parse(dayjs()) / 1000) {
		wx.removeStorageSync(k); 
		wx.removeStorageSync(k + TIME_SUFFIX); 
		return false;
	}
	
	// 检查数据是否存在
	return wx.getStorageSync(k) !== '';
}

/**
 * 删除
 */
function remove(k) {
	if (!k) return null;
	
	wx.removeStorageSync(k);
	wx.removeStorageSync(k + TIME_SUFFIX);
}

/**
 * 获取所有缓存键名
 * @returns {Array} 所有缓存键名数组
 */
function getAllKeys() {
	try {
		const res = wx.getStorageInfoSync();
		return res.keys || [];
	} catch (e) {
		console.error('获取缓存键名失败', e);
		return [];
	}
}

/**
 * 清除所有key
 */
function clear() {
	wx.clearStorageSync();
}

/**
 * 按缓存分组清除
 * @param {String} group 缓存组名
 */
function clearGroup(group) {
	if (!group) return;
	
	try {
		// 获取所有缓存键
		const keys = getAllKeys();
		
		// 获取组前缀
		const prefix = group + '_';
		
		// 筛选并清除符合前缀的键
		for (let i = 0; i < keys.length; i++) {
			const key = keys[i];
			// 如果键以分组前缀开头，则清除
			if (key.startsWith(prefix)) {
				remove(key);
				console.log(`已清除分组缓存: ${key}`);
			}
		}
	} catch (err) {
		console.error(`清除分组缓存失败(${group}):`, err);
	}
}

/**
 * 获取过期的缓存数据（用于网络请求失败时的降级策略）
 * @param {String} key - 缓存键名
 * @param {Number} maxAgeSeconds - 最大可接受的过期秒数，默认24小时
 */
function getExpired(key, maxAgeSeconds = 86400) {
    try {
        // 检查缓存是否存在
        const value = wx.getStorageSync(key);
        if (!value) return null;
        
        // 获取过期时间
        const deadtime = wx.getStorageSync(key + '_deadtime');
        if (!deadtime) return null;
        
        const now = parseInt(dayjs().valueOf() / 1000);
        
        // 检查是否过期，且过期时间不超过maxAgeSeconds
        if (deadtime < now && (now - deadtime) <= maxAgeSeconds) {
            console.warn(`使用过期缓存数据: ${key}, 过期时间: ${now - deadtime}秒`);
            return value;
        }
        
        // 过期时间超过maxAgeSeconds，不使用
        return null;
    } catch (err) {
        console.error('获取过期缓存失败:', err);
        return null;
    }
}

module.exports = {
	set,
	get,
	has,
	remove,
	getAllKeys,
	clear,
	clearGroup,
	getExpired,
	CACHE_GROUP,
	CACHE_PRIORITY
};